﻿/*
 * ShpSelectCommand.GetFeatureMetadata
 * 
 * initial implementation : 20.9.2008
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
using System.Text.RegularExpressions;
using System.Data;
using System.Data.Common;
using Petra.Gis.DataServices;
//using Petra.Gis.Geometry;
//using Petra.Gis.Geometry.Support;
using Petra.Gis.DataServices.Metadata;


namespace Petra.Gis.DataServices.SHP
{

  
  public partial class ShpSelectCommand : SpatialDbCommand
  {




    protected override FeatureMetadata getFeatureMetadata()
    {

      // if allready initialized, do nothing
      if (Metadata != null)
        return Metadata;

      if (this.CommandText == "" || this.CommandText == null)
        return null;

      if (this.Connection.State != ConnectionState.Open)
        return null;

      if (this.CommandType == CommandType.TableDirect)
      {
        FeatureQualifier tq = new FeatureQualifier()
        {
          Name = this.CommandText
        };
        if (tq == null)
          return null;
        else
        {
          //_metadata = getFeatureMetadata(tq.Catalog, tq.Schema, tq.Name);
          return getFeatureMetadata(tq.Catalog, tq.Schema, tq.Name);
        }
      }
      else
        return null;

      ////add metadata to extensions
      //if (this.Extensions.ContainsKey("FeatureMetadata"))
      //  this.Extensions["FeatureMetadata"] = _metadata;
      //else
      //  this.Extensions.Add("FeatureMetadata", _metadata);
    }
    




    protected override FeatureMetadata forceFeatureMetadata(string forceMetadataByFeatureName)
    {
      FeatureQualifier f = parseFeatureQualifierFromLongName(forceMetadataByFeatureName);
      return getFeatureMetadata(f.Catalog, f.Schema, f.Name);
    }





    protected override FeatureMetadata getFeatureMetadata(string catalog, string schema, string featureName)
    {
      // get feature/table metadata 
      DataTable mtdtT = this.Connection.GetSpatialSchema(SpatialSchemaTables.Features, new string[] { catalog, schema, featureName, null, null, null, null, null, null, null });

      if (mtdtT.Rows.Count != 1)
        throw new ArgumentException("invalid FeatureName specified, either not exists or ambiguitous");

      FeatureMetadata result = new FeatureMetadata()
      {
        Abstract = (string)mtdtT.Rows[0]["ABSTRACT"],
        Authority = (string)mtdtT.Rows[0]["AUTHORITY"],
        Name = (string)mtdtT.Rows[0]["FEATURE_NAME"],
        ContactInfo = ContactInfo.Parse((string)mtdtT.Rows[0]["CONTACTINFO"]),
        KeyWords = ((string)mtdtT.Rows[0]["KEYWORDS"]).Split(';'),
        Title = (string)mtdtT.Rows[0]["TITLE"],
        //Bounds = BoundingBox.Parse((string)mtdtT.Rows[0]["BOUNDS"])
      };

      // get geometry columns metadata
      DataTable mtdtTCS;
      mtdtT = this.Connection.GetSpatialSchema(SpatialSchemaTables.Fields, new string[] { catalog, schema, featureName, null, null, null, null });
      result.GeometryFieldsMetadata = new SpatialFieldMetadata[mtdtT.Rows.Count];
      for (int i = 0; i < mtdtT.Rows.Count; i++)
      {
        result.GeometryFieldsMetadata[i] = new SpatialFieldMetadata();
        result.GeometryFieldsMetadata[i].Name = (string)mtdtT.Rows[i]["FIELD_NAME"];
        // resolve coordinate systems...
        string csid = (mtdtT.Rows[i]["COORDINATESYSTEM_ID"]).ToString();
        mtdtTCS = this.Connection.GetSpatialSchema(SpatialSchemaTables.CoordinateSystemsInfo, new string[] { csid, null });
        //gdosql have proprietary cs definition in db, must use parseCoordinateSystemInfo
        if (mtdtTCS.Rows[0]["COORDINATESYSTEM_INFO"] is System.DBNull)
          throw new ApplicationException("null COORDINATESYSTEM_INFO, cant create metadata");
        else
          result.GeometryFieldsMetadata[i].SRS = parseCoordinateSystemInfo((string)mtdtTCS.Rows[0]["COORDINATESYSTEM_INFO"]);

        //resolve domain geometry type
        switch ((ShapeGeometryTypes)mtdtT.Rows[0]["DOMAIN_GEOMETRY_TYPE"])
        {
          case ShapeGeometryTypes.Point:
          case ShapeGeometryTypes.PointM:
          case ShapeGeometryTypes.PointZ:
            result.GeometryFieldsMetadata[i].DomainType = DomainGeometryTypeEnum.Point;
            break;
          case ShapeGeometryTypes.Polygon:
          case ShapeGeometryTypes.PolygonM:
          case ShapeGeometryTypes.PolygonZ:
            result.GeometryFieldsMetadata[i].DomainType = DomainGeometryTypeEnum.Surface;
            break;
          //case ShapeGeometryTypes.:
          //  result.GeometryFieldsMetadata[i].DomainType = DomainGeometryTypeEnum.Mixed;
          //  break;
          //case 5:
          //case 33:
          //  result.GeometryFieldsMetadata[i].DomainType = DomainGeometryTypeEnum.Label;
          //  break;
          case ShapeGeometryTypes.LineString:
          case ShapeGeometryTypes.LineStringM:
          case ShapeGeometryTypes.LineStringZ:
            result.GeometryFieldsMetadata[i].DomainType = DomainGeometryTypeEnum.Line;
            break;
          //case ShapeGeometryTypes.:
          //  result.GeometryFieldsMetadata[i].DomainType = DomainGeometryTypeEnum.Mixed;
          //  break;
          //case 4:
          //  result.GeometryFieldsMetadata[i].DomainType = DomainGeometryTypeEnum.Grid;
          //  break;
          default:
            throw new ApplicationException("invalid shp domain geometry type " + mtdtT.Rows[0]["DOMAIN_GEOMETRY_TYPE"].ToString());
        }
      }
      return result;
    }



  }
}
